/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Gtk;
using Glade;

using Anculus.Core;
using Anculus.Gui;

using Galaxium.Core;
using Galaxium.Client;
using Galaxium.Protocol;
using Galaxium.Protocol.Gui;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;

namespace Galaxium.Protocol.Aim.GtkGui
{
	public class AimAccountWidget : AbstractAccountWidget
	{
		[Widget ("txtPassword")]
		private Entry _txtPassword;
		[Widget ("chkAutoConnect")]
		private CheckButton _chkAutoConnect;
		[Widget ("chkRememberPassword")]
		private CheckButton _chkRememberPassword;
		[Widget ("lblAccount")]
		private Label _lblAccount;
		[Widget ("btnConnect")]
		private Button _btnConnect;
		[Widget ("btnCancel")]
		private Button _btnCancel;
		[Widget ("barProgress")]
		private ProgressBar _progressBar;
		[Widget ("removeButton")]
		private Button _removeButton;
		[Widget ("txtDisplayName")]
		private Entry _txtDisplayName;
		
		private ImageComboBox<IPresence> _cboStatus;
		private IPresence _presence;
		
		public AimAccountWidget () : base (AimProtocol.Instance)
		{
		}

		public override void Initialize ()
		{
			XML.CustomHandler = new XMLCustomWidgetHandler (CreateCustomWidget);
			_nativeWidget = GladeUtility.ExtractWidget<Widget> (GladeUtility.GetGladeResourceStream (typeof (AimAccountWidget).Assembly, "AccountWidget.glade"), "widget", this);
			_layout_widget = _lblAccount;
			
			_btnConnect.Sensitive = false;
			_btnCancel.Sensitive = false;
			_btnConnect.Image = new Image (IconUtility.GetIcon ("galaxium-ok", IconSizes.Small));
			_btnCancel.Image = new Image (IconUtility.GetIcon ("galaxium-cancel", IconSizes.Small));

			//InitializeBase ();
		}

		public override void Connect ()
		{
			OnConnectClicked (this, new EventArgs ());
		}
		
		private Widget CreateCustomWidget (XML gxml, string func_name, string name, string string1, string string2, int int1, int int2)
		{
			if (name == "cboStatusPlaceHolder") {
				_cboStatus = CreateStatusCombo (AimPresence.Online, //the selected one
					AimPresence.Online, AimPresence.Away, AimPresence.Invisible);
				return _cboStatus;
			} else if (name == "cboAccountPlaceHolder") {
				_accountCombo = CreateAccountCombo ();
				return _accountCombo;
			}

			return new Label ("ERROR");
		}

		protected override IAccount SetAccount ()
		{
			AimAccount account = GetAccount(_accountCombo.Entry.Text) as AimAccount;
			
			if (account != null) {
				account.DisplayName = _txtDisplayName.Text;
				account.Password = _txtPassword.Text;
				account.AutoConnect = _chkAutoConnect.Active;
				account.RememberPassword = _chkRememberPassword.Active;
				account.InitialPresence = GetInitialPresence ();
				
				return account;
			} else {
				AimAccount newAccount = new AimAccount (_accountCombo.Entry.Text, _txtPassword.Text, _txtDisplayName.Text, _chkAutoConnect.Active, _chkRememberPassword.Active);
				newAccount.InitialPresence = GetInitialPresence ();
				
				AccountUtility.AddAccount (newAccount);
				
				return newAccount;
			}
		}

		private IPresence GetInitialPresence ()
		{
			if (_presence == null)
			{
				TreeIter iter;
				
				if (_cboStatus.GetActiveIter (out iter))
					_presence = _cboStatus.Model.GetValue (iter, 0) as IPresence;
				else
					_presence = UnknownPresence.Instance;
			}
			return _presence;
		}
		
		protected override Gdk.Pixbuf PresenceImageLookup (IPresence item)
		{
			return IconUtility.GetIcon (AimPresence.GetIconString (item), IconSizes.Small);
		}

		private void OnConnectClicked (object sender, EventArgs args)
		{
			AimSession session = CreateSession () as AimSession;
			if (session == null) //the selected account is in use
				return;
			
			//session.Connection.ErrorOccurred += new ConnectionErrorEventHandler (ConnectionErrorOccurred);
			//session.Usurped += new SessionEventHandler (SessionUsurped);
			session.Disconnected += SessionDisconnected;
			
			session.Connect ();
			
			DisableFields (true);
		}
		
		private void RemoveButtonClicked (object sender, EventArgs args)
		{
			RemoveSelectedAccount ();
		}
		
		private void OnCancelClicked (object sender, EventArgs args)
		{
			if (_current_session != null)
				_current_session.Disconnect ();
			
			CancelLogin ();
		}
		
		private void SessionUsurped (object sender, SessionEventArgs args)
		{
		
				EnableFields ();
				
				_progressBar.Fraction = 0.0;
				_progressBar.Text = "Session Usurped!";
				
				OnCloseSessionWidget (args);
			
			SoundSetUtility.Play(Sound.Disconnected);
		}

		protected override void SessionDisconnected (object sender, SessionEventArgs args)
		{
		
				EnableFields ();

			base.SessionDisconnected (sender, args);
		}

		protected virtual void ConnectionErrorOccurred (object sender, ConnectionErrorEventArgs args)
		{
			ErrorOccurred (args.Description);
		}
		
		protected override void ErrorOccurred (string error)
		{
		
				UpdateProgress (error, 0.0);
				
				EnableFields ();
		}
		
		protected override void UpdateProgress (string message, double percent)
		{
			_progressBar.Text = message;
			_progressBar.Fraction = percent;
		}

		private void RememberPasswordToggled (object sender, EventArgs args)
		{
		}
		
		private void AutoConnectToggled (object sender, EventArgs args)
		{
		}
		
		private void DisplayNameChanged (object sender, EventArgs args)
		{
			_btnConnect.Sensitive = CheckInput ();
		}
		
		private void PasswordChanged (object sender, EventArgs args)
		{
			_btnConnect.Sensitive = CheckInput ();
		}
		
		protected override void AccountNameChanged (object sender, EventArgs args)
		{
			LoadAccountInfo ();
			_btnConnect.Sensitive = CheckInput ();
		}
		
		private void LoadAccountInfo ()
		{
			AimAccount account = AccountUtility.GetAccount(_protocol, _accountCombo.Entry.Text) as AimAccount;
			
			if (account != null)
			{
				_txtDisplayName.Text = account.DisplayName;
				_txtPassword.Text = account.Password;
				_chkAutoConnect.Active = account.AutoConnect;
				_cboStatus.Select (account.InitialPresence);
				_chkRememberPassword.Active = account.RememberPassword;
			}
		}
		
		private bool CheckInput ()
		{
			if (_txtDisplayName.Text.Length == 0 || _txtPassword.Text.Length == 0 || _accountCombo.Entry.Text.Length == 0)
				return false;
			
			return true;
		}
		
		public override void EnableFields ()
		{
			OnEnableChange (EventArgs.Empty);
			
			_btnConnect.Sensitive = true;
			
			if (SessionUtility.Count >= 1)
				_btnCancel.Sensitive = true;
			else
				_btnCancel.Sensitive = false;
			
			
			_chkRememberPassword.Sensitive = true;
			_chkAutoConnect.Sensitive = true;
			_txtDisplayName.Sensitive = true;
			_txtPassword.Sensitive = true;
			_accountCombo.Sensitive = true;
			_cboStatus.Sensitive = true;
			_removeButton.Sensitive = true;
		}
		
		public override void DisableFields (bool omit_cancel)
		{
			OnDisableChange (EventArgs.Empty);
			
			_btnConnect.Sensitive = false;
			_btnCancel.Sensitive = omit_cancel;
			
			_chkRememberPassword.Sensitive = false;
			_chkAutoConnect.Sensitive = false;
			_txtDisplayName.Sensitive = false;
			_txtPassword.Sensitive = false;
			_accountCombo.Sensitive = false;
			_cboStatus.Sensitive = false;
			_removeButton.Sensitive = false;
		}
	}
}